package com.xgq.drink.controller;

import cn.hutool.log.Log;
import com.alipay.api.domain.StoreInfo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xgq.drink.annotation.RequiresRole;
import com.xgq.drink.entity.Brand;
import com.xgq.drink.entity.LoginUser;
import com.xgq.drink.entity.R;
import com.xgq.drink.entity.User;
import com.xgq.drink.utils.JwtTokenUtil;
import com.xgq.drink.utils.RUtils;
import com.xgq.drink.utils.RedisUtil;
import com.xgq.drink.utils.SmsUtil;
import com.xgq.drink.service.IUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SmsUtil sendSms;
    @PostMapping("/login")
    @Tag(name = "用户模块", description = "用户相关接口")
    @io.swagger.v3.oas.annotations.Operation(
            summary = "用户登录接口",
            description = "用户通过用户名和密码进行登录",
            responses = {
                    @ApiResponse(responseCode = "200", description = "登录成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "400", description = "登录失败",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R login(@RequestBody User user) {
        try {
            User userDB = userService.login(user);
            String token = jwtTokenUtil.generateToken(userDB.getUserId());
            System.out.println(token);
            return RUtils.success("登录成功！", token);
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }
    @PostMapping("/loginByPhone")
    @Tag(name = "用户模块", description = "用户相关接口")
    @io.swagger.v3.oas.annotations.Operation(
            summary = "手机号登录接口",
            description = "用户通过手机号和验证码进行登录",
            responses = {
                    @ApiResponse(responseCode = "true", description = "登录成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "登录失败",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R loginByPhone(@RequestBody LoginUser loginUser) {
        try {
            User userDB = userService.loginByPhone(loginUser.getUser().getPhone(), loginUser.getCode());
            String token = jwtTokenUtil.generateToken(userDB.getUserId());
            return RUtils.success("登录成功！", token);
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }
    @PostMapping("/register")
    @Tag(name = "用户模块", description = "用户相关接口")
    @io.swagger.v3.oas.annotations.Operation(
            summary = "用户注册接口",
            description = "用户通过手机号、密码、验证码进行注册",
            responses = {
                    @ApiResponse(responseCode = "true", description = "注册成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "注册失败，用户名已存在",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R register(@RequestBody LoginUser user) {
        return userService.register(user);
    }
    @GetMapping("/info")
    @Tag(name = "用户模块", description = "用户相关接口")
    @io.swagger.v3.oas.annotations.Operation(
            summary = "用户获取个人信息",
            description = "用户通过token获取个人信息",
            responses = {
                    @ApiResponse(responseCode = "true", description = "获取成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "用户不存在",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R getUserInfo(HttpServletRequest request) {
        System.out.println("获取用户信息");
        String token = request.getHeader("Authorization");
        String userId = jwtTokenUtil.getUserIdFromToken(token);
        // 处理业务逻辑
        if (userId != null) {
            return RUtils.success("获取成功", userService.GetUserByUserId(userId));
        } else {
            return RUtils.fail("获取失败");
        }
    }
    @PostMapping("/logout")
    @Tag(name = "用户模块", description = "用户相关接口")
    @Operation(
            summary = "用户退出登录接口",
            description = "用户通过token退出登录",
            responses = {
                    @ApiResponse(responseCode = "true", description = "退出成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "退出失败",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R logout(HttpServletRequest request) {
        try {
            String token = request.getHeader("Authorization");
            if (token != null && token.startsWith("Bearer ")) {
                token = token.substring(7);
            }
            if (token == null) {
                return RUtils.fail("Token不存在");
            }

            // 获取Token剩余时间
            long expiration = jwtTokenUtil.getExpirationFromToken(token);

            // 无论是否过期，均加入黑名单
            if (expiration > 0) {
                // 未过期：按剩余时间设置
                redisUtil.setTokenBlacklist(token, expiration);
                System.out.println("Token未过期，加入黑名单，有效期至剩余时间: " + expiration + "ms");
            } else {
                // 已过期：设置一个较短的有效期（如5分钟），避免Redis堆积无效数据
                redisUtil.setTokenBlacklist(token, 5 * 60 * 1000); // 5分钟
                System.out.println("Token已过期，加入黑名单5分钟");
            }

            // 清除Security上下文
            SecurityContextHolder.clearContext();
            return RUtils.success("已退出");
        } catch (Exception e) {
            e.printStackTrace();
            return RUtils.fail("退出失败: " + e.getMessage());
        }
    }
    @PostMapping("/sendSms")
    @Tag(name = "用户模块", description = "用户相关接口")
    @io.swagger.v3.oas.annotations.Operation(
            summary = "发送验证码接口",
            description = "用户通过手机号发送验证码",
            responses = {
                    @ApiResponse(responseCode = "true", description = "发送成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "发送失败",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R sendSms(@RequestBody String phone) {
        String cleanedPhone = phone.replace("=", "");
        System.out.println("验证码"+cleanedPhone);
        try {
            // 检查是否在 1 分钟内已经发送过验证码
            String key = "sms:" + cleanedPhone;
            if (redisUtil.isTokenBlacklisted(key)) {
                return RUtils.fail("请勿频繁发送验证码！");
            }

            // 发送验证码
            String code = sendSms.sendSms(cleanedPhone);

            // 将验证码存储到 Redis，设置 1 分钟过期,测试10分钟过期
            redisUtil.set(key, code, 100, TimeUnit.MINUTES);

            return RUtils.success("验证码发送成功！");
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return RUtils.fail("验证码发送失败！");
        }
    }
    @PutMapping("/updateUser")
    @Tag(name = "用户模块", description = "用户相关接口")
    @Operation(
            summary = "修改用户信息",
            description = "根据用户ID修改用户信息",
            responses = {
                    @ApiResponse(responseCode = "true", description = "修改成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "用户不存在或参数错误",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R updateUser(@RequestBody LoginUser user,HttpServletRequest request) {
        user.getUser().setUserId(Long.valueOf(jwtTokenUtil.getUserIdFromToken(request.getHeader("Authorization"))));
        System.out.println(user);
        return userService.updateUser(user.getUser(),user.getCode());
    }
    @PutMapping("/updatePassword")
    @Tag(name = "用户模块", description = "用户相关接口")
    @Operation(
            summary = "修改密码",
            description = "通过手机验证码修改密码",
            responses = {
                    @ApiResponse(responseCode = "true", description = "修改成功"),
                    @ApiResponse(responseCode = "false", description = "验证码错误或用户不存在")
            }
    )
    public R updatePassword(@RequestBody Map<String, String> params, HttpServletRequest request) {
        String userId = jwtTokenUtil.getUserIdFromToken(request.getHeader("Authorization"));
        return userService.updatePassword(
                userId,
                params.get("phone"),
                params.get("code"),
                params.get("newPassword")
        );
    }

    @PutMapping("/updateInfo")
    @Tag(name = "用户模块", description = "用户相关接口")
    @Operation(
            summary = "修改基本信息",
            description = "修改用户头像、手机、邮箱、用户名等基本信息",
            responses = {
                    @ApiResponse(responseCode = "true", description = "修改成功"),
                    @ApiResponse(responseCode = "false", description = "用户不存在或参数错误")
            }
    )
    public R updateInfo(@RequestBody User user, HttpServletRequest request) {
        user.setUserId(Long.valueOf(jwtTokenUtil.getUserIdFromToken(request.getHeader("Authorization"))));
        return userService.updateUserInfo(user);
    }
//    店铺
    @PostMapping("/loginStore")
    @Tag(name = "店铺模块", description = "店铺相关接口")
    @Operation(summary = "店铺登录(第一步)", description = "复用登录逻辑获取品牌列表")
    public R loginStore(@RequestBody LoginUser loginRequest) {
        try {
            User userDB = resolveLogin(loginRequest);
            List<Brand> brands = userService.getUserBrands(userDB.getUserId());
            if (brands.isEmpty()) {
                return RUtils.fail("用户未关联任何品牌");
            }
            return RUtils.success("登录成功", new StoreLoginResponse(brands, userDB));
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }

    // 添加在类末尾
    @Data
    @AllArgsConstructor
    private static class StoreLoginResponse {
        private List<Brand> brands;
        private User user;
    }

    @PostMapping("/confirmBrand")
    @Tag(name = "店铺模块", description = "店铺相关接口")
    @Operation(summary = "确认店铺选择", description = "生成带店铺上下文的Token")
    public R confirmStore(@RequestParam String brandId,@RequestParam String userId) {
        System.out.println("----");
        try {
            if (!userService.validateStorePermission(userId, Long.valueOf(brandId))) {
                return RUtils.fail("无效的店铺选择");
            }

            // 生成带店铺上下文的Token
            String token = jwtTokenUtil.generateStoreToken(userId, Long.valueOf(brandId));
            return RUtils.success("登录成功", token);
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }
    @GetMapping("/getStoreInfo")
    @RequiresRole(value = {"STORE_OWNER", "STORE_STAFF"}, brandRequired = true)
    @Tag(name = "商家模块", description = "商家获取信息接口")
    @io.swagger.v3.oas.annotations.Operation(
            summary = "用户获取店铺信息",
            description = "用户获取店铺信息",
            responses = {
                    @ApiResponse(responseCode = "true", description = "获取成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "店铺不存在",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R getStoreInfo(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Long userId =jwtTokenUtil.getStoreIdFromToken(token);
        Long brandId = jwtTokenUtil.getStoreIdFromToken(token);
        // 处理业务逻辑
        if (userId != null&&brandId != null) {
            Brand brand = userService.GetBrandByUserIdAndBrandId(Long.valueOf(userId),Long.valueOf(brandId));
            if (brand != null) {
                return RUtils.success("获取成功", brand);
            }else {
                return RUtils.fail("获取失败");
            }
        } else {
            return RUtils.fail("获取失败");
        }
    }
    @GetMapping("/storeInfo")
    @Tag(name = "用户模块", description = "用户相关接口")
    @io.swagger.v3.oas.annotations.Operation(
            summary = "用户获取店铺信息",
            description = "用户获取店铺信息",
            responses = {
                    @ApiResponse(responseCode = "true", description = "获取成功",
                            content = @Content(schema = @Schema(implementation = R.class))),
                    @ApiResponse(responseCode = "false", description = "店铺不存在",
                            content = @Content(schema = @Schema(implementation = R.class)))
            }
    )
    public R storeInfo(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Long userId =jwtTokenUtil.getStoreIdFromToken(token);
        // 处理业务
        if (userId != null) {
            Brand brand = userService.GetBrandByUserId(Long.valueOf(userId));
            System.out.println(brand);
            User user = userService.GetUserByUserId(jwtTokenUtil.getUserIdFromToken(token));
            // 创建组合返回对象
            Map<String, Object> result = new HashMap<>();
            result.put("brand", brand);
            result.put("user", user);
            return RUtils.success("获取成功", result);
        } else {
            return RUtils.fail("获取失败");
        }
    }
    private User resolveLogin(LoginUser loginUser) throws Exception {
        if (loginUser.getCode()==""||loginUser.getCode()==null) {
            // 账号密码登录
            return userService.login(loginUser.getUser());
        } else {
            // 手机验证码登录
            System.out.println("--------");
            System.out.println(loginUser);
            return userService.loginByPhone(
                    loginUser.getUser().getPhone(),
                    loginUser.getCode()
            );
        }
    }

    @PostMapping("/create")
    @RequiresRole(value = {"ADMIN","PLATFORM_ADMIN"}, brandRequired = true)
    @Operation(summary = "创建用户", description = "创建新用户")
    public R createUser(@RequestBody User user) {
        try {
            String encryptedPassword = passwordEncoder.encode(user.getPassword());
            user.setPassword(encryptedPassword);
            if (userService.save(user)) {
                return RUtils.success("用户创建成功");
            }
            return RUtils.fail("用户创建失败");
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }

    @PutMapping("/update")
    @RequiresRole(value = {"ADMIN","PLATFORM_ADMIN"}, brandRequired = true)
    @Operation(summary = "更新用户信息", description = "更新用户详细信息")
    public R updateUser(@RequestBody User user) {
        try {
            User existUser = userService.getById(user.getUserId());
            if (existUser == null) {
                return RUtils.fail("用户不存在");
            }
            if (user.getPassword() != null) {
                // 加密密码
                String encryptedPassword = passwordEncoder.encode(user.getPassword());
                user.setPassword(encryptedPassword);
            }
            // 保留敏感字段
            user.setIsActive(null);
            return userService.updateById(user) ?
                    RUtils.success("更新成功") : RUtils.fail("更新失败");
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }

    @PutMapping("/disable/{userId}")
    @RequiresRole(value = {"ADMIN","PLATFORM_ADMIN"}, brandRequired = true)
    @Operation(summary = "禁用用户", description = "禁用指定用户")
    @Parameter(name = "userId", description = "用户ID", required = true)
    public R disableUser(@PathVariable Long userId) {
        try {
            User user = new User();
            user.setUserId(userId);
            user.setIsActive((byte) 1); // 假设1表示禁用状态
            return userService.updateById(user) ?
                    RUtils.success("用户已禁用") : RUtils.fail("操作失败");
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }
    @PutMapping("/open/{userId}")
    @RequiresRole(value = {"ADMIN","PLATFORM_ADMIN"}, brandRequired = true)
    @Operation(summary = "启用用户", description = "启用指定用户")
    @Parameter(name = "userId", description = "用户ID", required = true)
    public R openUser(@PathVariable Long userId) {
        try {
            User user = new User();
            user.setUserId(userId);
            user.setIsActive((byte) 0); // 假设1表示禁用状态
            return userService.updateById(user) ?
                    RUtils.success("用户已启用") : RUtils.fail("操作失败");
        } catch (Exception e) {
            return RUtils.fail(e.getMessage());
        }
    }
    @GetMapping("/list")
    @RequiresRole(value = {"ADMIN","PLATFORM_ADMIN"}, brandRequired = true)
    @Operation(summary = "分页查询用户", description = "根据条件分页查询用户列表")
    public R getUserList(
            @RequestParam(required = false) String username,
            @RequestParam(required = false) Integer isDisabled,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) Integer gender,
            @RequestParam(required = false) Integer minPoints,
            @RequestParam(required = false) Integer maxPoints,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime,
            @RequestParam(defaultValue = "1") int current,
            @RequestParam(defaultValue = "10") int size) {

        Page<User> page = new Page<>(current, size);
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        // 构建查询条件
        wrapper.like(StringUtils.isNotBlank(username), "username", username)
                .eq(isDisabled != null, "is_disabled", isDisabled)
                .like(StringUtils.isNotBlank(phone), "phone", phone)
                .eq(gender != null, "gender", gender)
                .ge(minPoints != null, "points", minPoints)
                .le(maxPoints != null, "points", maxPoints)
                .ge(startTime != null, "create_time", startTime)
                .le(endTime != null, "create_time", endTime);

        return RUtils.success("查询成功", userService.page(page, wrapper));
    }
}